---@class GridLayout
GridLayout = { }

function GridLayout:New(root,prefab)
    local grid = {};
    setmetatable(grid, self);
    self.__index = GridLayout

    grid.root = root.transform
    grid.rootRectTransform = grid.root:GetComponent("RectTransform")
    if prefab ~= nil then
        grid.prefab = prefab.gameObject
    end


    grid.childList = {}
    grid.index = 1
    grid.finalHeight = 0 --记录最后一个item高度
    grid.curHeight = 0 --下一个item生成的位置
    grid.pagePositionList = {} -- 翻页位置
    grid.aimPositionX = nil --需移动到翻页的位置
    --以下参数需要初始化
    --分页
    grid.pageOffsetX = -332 --每页X轴偏移量
    grid.pageInterval = 664 --每页间距
    grid.pageCount = 0 --分页，每页多少个item(分页功能开关)
    --分页

    grid.defaultHeight = 135 --默认间隔
    grid.defaultScrollY = -83 --生成第一个item的位置
    grid.childX = 0 --生成时，每个item，x轴向偏移
    grid.downward = true --默认向下排序

    return grid;
end

function GridLayout:SetDefault(defaultHeight,defaultScrollY,downward)
    self.defaultScrollY = defaultScrollY
    self.defaultHeight = defaultHeight
    self.downward = downward
end

---只生成对象不排序
function GridLayout:AddChildNoSort(name,prefab)
    if self.prefab == nil and prefab == nil then return nil end
    self.childList[self.index] = {}
    local obj = newObject(self.prefab or prefab)
    obj.transform:SetParent(self.root);
    Util.Lua_SetLocalScaleXYZ(obj.transform,1,1,1)
    obj.gameObject:SetActive(true)
    obj.gameObject.name = name
    local list = self.childList[self.index]
    list.gameObject = obj
    list.height = self.defaultHeight
    list.name = name
    self.index = self.index + 1
    return obj
end

function GridLayout:AddChild(name)
    if self.prefab == nil then return nil end
    local obj = self:AddChildNoSort(name)
    self:RefreshList()
    return obj
end

function GridLayout:GetItemByName(name)
    for k,v in pairs(self.childList) do
        if tostring(v.name) == tostring(name) then
            return v.gameObject
        end
    end
    return nil
end

function GridLayout:ClearAll()
    if self.root == nil then return end
    for k,v in pairs(self.childList) do
        v.gameObject.gameObject:Destroy()
    end
    self.childList = {}
    self.pagePositionList = {}
    self.curHeight = 0
    self.finalHeight = 0
    self.index = 1

end

function GridLayout:GetAllChild()
    local temp = {}
    for k,v in pairs(self.childList) do
        table.insert(temp,v.gameObject)
    end
    return temp
end

function GridLayout:GetHeight()
    return Mathf.Abs(self.curHeight)
end

function GridLayout:HideRoot(visible)
    if type(visible) == "boolean" then
        self.root.gameObject:SetActive(not visible)
    end
end

function GridLayout:RefreshList()
    self.curHeight = 0
    local index = 0
    for k,v in pairs(self.childList) do
        index = index + 1
        local obj = v.gameObject
        local height = v.height
        Util.Lua_SetLocalPositionXYZ(obj,self.childX,self. curHeight,0)
        self.curHeight = self.downward and self.curHeight - height or self.curHeight + height
        if index == #self.childList then
            self.finalHeight = height
        end
    end
end
---移动到某个位置1
function GridLayout:SetScrollValue(value)
    Util.EndOfFrame(function()
        local y = self.defaultScrollY
        if value == nil then
            if self.downward then
                local vec = Vector3(0,self.defaultScrollY,0)
                self.root:GetComponent("RectTransform").anchoredPosition3D = vec
            else
                local vec = Vector3(0,self.defaultScrollY - self.curHeight + self.finalHeight,0)
                self.root:GetComponent("RectTransform").anchoredPosition3D = vec
            end
            return
        end
        self.root.anchoredPosition3D = Vector3(0,value,0)
    end)
end

function GridLayout:GetScrollValue()
    return self.root.anchoredPosition3D.y
end

---移动到某个位置2
function GridLayout:DOLocalMove(vec,time)
    self.root:DOLocalMove(vec,time,false)
end

---某个item临时需要变更高度，全部item重新排列
function GridLayout:SetItemHeightByName(name,height)
    for k,v in pairs(self.childList) do
        if tostring(v.name) == tostring(name) then
            v.height = height
            self:RefreshList()
            return
        end
    end
end

---重置每个item高度，只处理数据
function GridLayout:ResetAllHeight(value)
    for k,v in pairs(self.childList) do
        v.height = value or self.defaultHeight
    end
end
---剧情列表、副本入口用 rectHeight滑动框高度
function GridLayout:ClampUpdate(rectHeight)
    if Input.GetMouseButton(0) then
        return
    end
    rectHeight = rectHeight - 20 ---渐变带高度
    local y =  self.root.anchoredPosition3D.y
    local lerpY = 0
    local finalHeight = self.defaultScrollY - self.curHeight - rectHeight
    if y < self.defaultScrollY or -self.curHeight < rectHeight then
        lerpY = Mathf.Lerp(y,self.defaultScrollY,Time.deltaTime * 10)
        self.root.anchoredPosition3D = Vector3(0,lerpY,0)
    elseif y > finalHeight then
        lerpY = Mathf.Lerp(y,finalHeight,Time.deltaTime * 10)
        self.root.anchoredPosition3D = Vector3(0,lerpY,0)
    end
end

---download == false 剧情显示专用
function GridLayout:ClampUpdate2()
    if Input.GetMouseButton(0) then
        return
    end
    local y =  self.root.anchoredPosition3D.y
    local lerpY = 0
    local finalHeight = self.defaultScrollY - Mathf.Abs(self.curHeight) + Mathf.Abs(self.finalHeight)
    if y  < finalHeight  then
        lerpY = Mathf.Lerp(y,finalHeight,Time.deltaTime * 10)
        self.root.anchoredPosition3D = Vector3(0,lerpY,0)
    elseif y > self.defaultScrollY then
        lerpY = Mathf.Lerp(y,self.defaultScrollY,Time.deltaTime * 10)
        self.root.anchoredPosition3D = Vector3(0,lerpY,0)
    end
end

---------------------------------翻页逻辑----------------------------------------
---根据当前位置自动翻页 update
function GridLayout:PageTurningHorizontal()
    if self.pageCount ~= 0 and Input.GetMouseButtonUp(0) == true then
        local rootX = Util.Lua_GetLocalPositionXYZ(self.root,0,0,0)
        local tempDistance = 10000000
        local result
        local index = 0
        for i =1, #self.pagePositionList do
            local distance = Mathf.Abs(rootX - self.pagePositionList[i])
            if distance < tempDistance then
                tempDistance = distance
                result = self.pagePositionList[i]
                index = i
            end
        end
        if result ~= nil then
            self.aimPositionX = result
            if self.pointGrid ~= nil then
                self.pointGrid:SetPagePointColor(index)
            end
        end
    end
    self:DOMove()
end

---翻页专用，移动到某个页面
function GridLayout:DOMove()
    if Input.GetMouseButton(0) == false and self.aimPositionX ~= nil then
        local x,y,z = Util.Lua_GetLocalPositionXYZ(self.root,0,0,0)
        local aimX = Mathf.Lerp(x,self.aimPositionX,Time.deltaTime * 5)
        local finish = Mathf.Abs(x - self.aimPositionX) < 0.1
        x = aimX
        Util.Lua_SetLocalPositionXYZ(self.root,x,y,z)
        if finish then self.aimPositionX = nil end
    end
end

---根据item初始化翻页信息
function GridLayout:InitPagePosition()
    if self.pageCount == 0 then return end
    self.pagePositionList = {}
    if self.pointGrid ~= nil then
        self.pointGrid:ClearAll()
    end
    local listY = self.pageOffsetX
    local itemIndex = 0
    local pointIndex = 1
    for k,v in pairs(self.childList) do
        if v.gameObject.gameObject.activeSelf then
            itemIndex = itemIndex + 1
        end
    end
    for i = 1, Mathf.Ceil(itemIndex / self.pageCount) do
        table.insert(self.pagePositionList,listY)
        listY = listY - self.pageInterval
        if self.pointGrid ~= nil then
            self.pointGrid:AddChild(pointIndex)
            pointIndex = pointIndex + 1
        end
    end
end
---初始化翻页点
function GridLayout:InitPagePoint(root,prefab)
    self.pointGrid = GridLayout:New(root,prefab)
end
function GridLayout:SetPagePointColor(index)
    local obj = self:GetItemByName(index)
    if obj ~= nil then
        for k,v in pairs(self.childList) do
            v.gameObject:GetComponent("Image").color = Color.gray
        end
        obj:GetComponent("Image").color = Color.white
    end
end

return GridLayout